package com.example.main;

import android.content.Context;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbRequest;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;


public class ScanGunActivity extends FragmentActivity {
    private static final String TAG = "ScanGunActivity";


    private TextView textView;


    //USB管理器:负责管理USB设备的类
    private UsbManager manager;
    //找到的USB设备
    private UsbDevice mUsbDevice;
    //代表USB设备的一个接口
    private UsbInterface mInterface;
    private UsbDeviceConnection mDeviceConnection;
    //代表一个接口的某个节点的类:写数据节点
    //private UsbEndpoint usbEpOut;
    //代表一个接口的某个节点的类:读数据节点
    private UsbEndpoint usbEpIn;
    //要发送信息字节
    private byte[] sendbytes;
    //接收到的信息字节
    private byte[] receiveytes;
    private HashMap<String, UsbDevice> deviceList;
    private Button read;

    private LinkedBlockingQueue<byte[]> linkedBlockingQueue = new LinkedBlockingQueue();
    private HashMap<Byte, String> hashMap = new HashMap<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.scan_gun);
        textView = findViewById(R.id.content);
        read = findViewById(R.id.read);
        initUsbData();
        initHashMap();
        thread();
        logic();
    }

    private void initHashMap() {
        hashMap.put((byte) 0x27, "0");
        hashMap.put((byte) 0x1e, "1");
        hashMap.put((byte) 0x1f, "2");
        hashMap.put((byte) 0x20, "3");
        hashMap.put((byte) 0x21, "4");
        hashMap.put((byte) 0x22, "5");
        hashMap.put((byte) 0x23, "6");
        hashMap.put((byte) 0x24, "7");
        hashMap.put((byte) 0x25, "8");
        hashMap.put((byte) 0x26, "9");
    }

    private List<byte[]> content = new ArrayList<>();

    private void logic() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        byte[] data = linkedBlockingQueue.take();
                        if (data != null && isHaveDate(data)) {
                            if (data[2] == 0x53) {
                                content.clear();
                            } else if (data[2] == 0x28) {
                                Log.i(TAG, "logic: finish");
                                showValue();
                            } else {
                                content.add(data);
                            }
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        }).start();
    }

    private boolean isHaveDate(byte[] data) {
        for (byte d : data) {
            if (d != 0) {
                return true;
            }
        }
        return false;
    }

    private void showValue() {
        final StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < content.size(); i++) {
            byte key = content.get(i)[2];
            stringBuffer.append(hashMap.get(key));
            Log.i(TAG, "showValue: " + byte2Hex(content.get(i)));
        }
        Log.i(TAG, "totoal: " + stringBuffer.toString());
        final String value = stringBuffer.toString();
        textView.post(new Runnable() {
            @Override
            public void run() {
                textView.setText(value);
            }
        });
    }


    private void thread() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    threadLogic();
                }

            }
        }).start();
    }

    private void initUsbData() {
        manager = (UsbManager) getSystemService(Context.USB_SERVICE);
        deviceList = manager.getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
        while (deviceIterator.hasNext()) {
            mUsbDevice = deviceIterator.next();
            Log.e("ldm", "vid=" + mUsbDevice.getVendorId() + "---pid=" + mUsbDevice.getProductId());

            if (6353 == mUsbDevice.getVendorId() && 11 == mUsbDevice.getProductId()) {//找到指定设备
                break;
            }

        }

        //获取设备接口

        for (int i = 0; i < mUsbDevice.getInterfaceCount(); i++) {
            // 一般来说一个设备都是一个接口，你可以通过getInterfaceCount()查看接口的个数
            // 这个接口上有两个端点，分别对应OUT 和 IN
            UsbInterface usbInterface = mUsbDevice.getInterface(i);
            mInterface = usbInterface;
            break;

        }
        //用UsbDeviceConnection 与 UsbInterface 进行端点设置和通讯

//        if (mInterface.getEndpoint(1) != null) {
//            usbEpOut = mInterface.getEndpoint(1);
//        }
        if (mInterface.getEndpoint(0) != null) {
            usbEpIn = mInterface.getEndpoint(0);
        }

        if (mInterface != null) {
            // 判断是否有权限
            if (manager.hasPermission(mUsbDevice)) {
                // 打开设备，获取 UsbDeviceConnection 对象，连接设备，用于后面的通讯
                mDeviceConnection = manager.openDevice(mUsbDevice);
                if (mDeviceConnection == null) {
                    return;
                }

                if (mDeviceConnection.claimInterface(mInterface, true)) {
                    Toast.makeText(this, "找到设备接口", Toast.LENGTH_SHORT).show();
                } else {
                    mDeviceConnection.close();
                }
            } else {
                Toast.makeText(this, "没有权限", Toast.LENGTH_SHORT).show();
            }
        } else {
            Toast.makeText(this, "没有找到设备接口", Toast.LENGTH_SHORT).show();
        }

    }


    private void readFromUsb() {
        int inMax = usbEpIn.getMaxPacketSize();
        ByteBuffer byteBuffer = ByteBuffer.allocate(inMax);
        UsbRequest usbRequest = new UsbRequest();
        usbRequest.initialize(mDeviceConnection, usbEpIn);
        usbRequest.queue(byteBuffer, inMax);
        if (mDeviceConnection.requestWait() == usbRequest) {
            byte[] retData = byteBuffer.array();
            try {
                Toast.makeText(this, "收到数据" + retData.length, Toast.LENGTH_SHORT).show();
                String value = new String(retData, "UTF-8");
                textView.setText(String.valueOf(value));
//            textView.setText(String.valueOf(byte2Hex(retData)));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

        }

    }


    private void threadLogic() {
        int inMax = usbEpIn.getMaxPacketSize();
        ByteBuffer byteBuffer = ByteBuffer.allocate(inMax);
        UsbRequest usbRequest = new UsbRequest();
        usbRequest.initialize(mDeviceConnection, usbEpIn);
        usbRequest.queue(byteBuffer, inMax);
        if (mDeviceConnection.requestWait() == usbRequest) {
            byte[] retData = byteBuffer.array();
            linkedBlockingQueue.add(retData);

            //Log.i(TAG, "threadLogic: " + byte2Hex(retData));
//            for (Byte byte1 : retData) {
//                Log.i(TAG, "threadLogic: " + byte1);
//            }
        }
    }

    private static String byte2Hex(byte[] bytes) {
        StringBuffer stringBuffer = new StringBuffer();
        String temp = null;
        for (int i = 0; i < bytes.length; i++) {
            temp = Integer.toHexString(bytes[i] & 0xFF);
            if (temp.length() == 1) {
                stringBuffer.append("0");
            }
            stringBuffer.append(temp);
            stringBuffer.append(" ");
        }

        return stringBuffer.toString();
    }

    private boolean configUsb340(int paramInt) {
        byte[] arrayOfByte = new byte[8];
        mDeviceConnection.controlTransfer(192, 95, 0, 0, arrayOfByte, 8, 1000);
        mDeviceConnection.controlTransfer(64, 161, 0, 0, null, 0, 1000);
        long l1 = 1532620800 / paramInt;
        for (int i = 3; ; i--) {
            if ((l1 <= 65520L) || (i <= 0)) {
                long l2 = 65536L - l1;
                int j = (short) (int) (0xFF00 & l2 | i);
                int k = (short) (int) (0xFF & l2);
                mDeviceConnection.controlTransfer(64, 154, 4882, j, null, 0, 1000);
                mDeviceConnection.controlTransfer(64, 154, 3884, k, null, 0, 1000);
                mDeviceConnection.controlTransfer(192, 149, 9496, 0, arrayOfByte, 8, 1000);
                mDeviceConnection.controlTransfer(64, 154, 1304, 80, null, 0, 1000);
                mDeviceConnection.controlTransfer(64, 161, 20511, 55562, null, 0, 1000);
                mDeviceConnection.controlTransfer(64, 154, 4882, j, null, 0, 1000);
                mDeviceConnection.controlTransfer(64, 154, 3884, k, null, 0, 1000);
                mDeviceConnection.controlTransfer(64, 164, 0, 0, null, 0, 1000);
                return true;
            }
            l1 >>= 3;
        }
    }

}

